#include "MiniParaSurfaceHandler.h"

MiniParaSurfaceHandler::MiniParaSurfaceHandler(MiniObject *obj)
    : MiniHandler(obj)
{
    UpdateHandler();
}

float MiniParaSurfaceHandler::CheckCollision(QPointF pos, QMatrix4x4 projection)
{
    // 之后增加选中程序
    Q_UNUSED(pos)
    Q_UNUSED(projection)
    return 1;
}

void MiniParaSurfaceHandler::ChangeVertex(Vector3f dv)
{
    Q_UNUSED(dv)
}

void MiniParaSurfaceHandler::UpdateHandler()
{
    InitHandler();

    // 转化为 B 样条曲面类型
    MiniParaSurface *surface = (MiniParaSurface*)m_object;

    Real bu = surface->GetUBegin();
    Real eu = surface->GetUEnd();
    Real bv = surface->GetVBegin();
    Real ev = surface->GetVEnd();
    float* vertices = new float[100*100*6];
    unsigned int* indices = new unsigned int[99*99*6];
    for (int i = 0; i < 99; i++)
    {
        for (int j = 0; j < 99; j++)
        {
            // 四边形分割成两个三角形
            int k = i * 99 + j;
            indices[k * 6 + 0] = i * 100 + j;
            indices[k * 6 + 1] = i * 100 + j + 1;
            indices[k * 6 + 2] = (i + 1) * 100 + j;
            indices[k * 6 + 3] = i * 100 + j + 1;
            indices[k * 6 + 4] = (i + 1) * 100 + j + 1;
            indices[k * 6 + 5] = (i + 1) * 100 + j;
        }
    }

    for (int i = 0; i < 100; i++)
    {
        for (int j = 0; j < 100; j++)
        {
            int k = i * 100 + j;

            float u = bu + (eu - bu) / 99 * i;
            float v = bv + (ev - bv) / 99 * j;

            Vector3f S = surface->SurfacePoint(u, v);
            vertices[k * 6 + 0] = S.x();
            vertices[k * 6 + 1] = S.y();
            vertices[k * 6 + 2] = S.z();

            Vector3f n = cross(surface->SurfaceParUPoint(u, v), surface->SurfaceParVPoint(u, v));
            n = normalize(n);
            vertices[k * 6 + 3] = n.x();
            vertices[k * 6 + 4] = n.y();
            vertices[k * 6 + 5] = n.z();
        }
    }

    // 储存数据
    m_countIndices.push_back(99*99*6);
    m_countVertices.push_back(100*100*2);
    m_vertices.push_back(vertices);
    m_indices.push_back(indices);
    m_modes.push_back(GL_TRIANGLES);
    m_color.push_back(m_basisColor);
    m_lineWidth.push_back(1);
}
